//
// Created by bill3000 on 3/3/21.
//

#include <sys/time.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>

#include "fruit.hpp"
#include "../log/logger.hpp"

cv::VideoCapture * FruitFSM::util_get_cam_by_id(int id) {
    cv::VideoCapture *cam = cam1;
    id==1?cam=cam1:(id==2?cam=cam2:(id==3?cam=cam3:(id==4?cam=cam4:cam1)));
    return cam;
}

std::string FruitFSM::util_get_now_time_milli_string() {
    struct timeval tv = {0};
    gettimeofday(&tv, nullptr);
    long long milli = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    char cs[128];
    sprintf(cs, "%lld", milli);
    std::string ss(cs);
    return ss;
}

void FruitFSM::util_delete_dir_content(const char* path) {
    DIR *pDir;
    struct dirent *de;
    char szFileName[128];
    char szFolderName[128];

    strcpy(szFolderName, path);
    strcat(szFolderName, "/%s");
    if ((pDir = opendir(path)) != nullptr)
    {
        while ((de = readdir(pDir)) != nullptr)
        {
            if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0)
            {
                sprintf(szFileName, szFolderName, de->d_name);
                std::string tmp = szFileName;
                if (tmp.find('.') == -1){
                    util_delete_dir_content(szFileName);
                }
                remove(szFileName);
            }
        }
    }

    if (pDir != nullptr)
    {
        closedir(pDir);
    }
}

void FruitFSM::util_get_dir_content(const std::string &path, std::vector<std::string> &fns) {
    DIR *dir;
    struct dirent *ptr;

    if ((dir = opendir(path.c_str())) == nullptr)
    {
        perror("Open dir error...");
        exit(1);
    }

    while ((ptr = readdir(dir)) != nullptr) {
        if (ptr->d_type == DT_REG)
            fns.emplace_back(ptr->d_name);
    }
    closedir(dir);
    sort(fns.begin(),fns.end());
}

int FruitFSM::util_copy_file(const std::string& sdir, const std::string& fn, const std::string& ddir) {
    std::string s = sdir;
    s.append(fn);
    std::string d = ddir;
    d.append(fn);

    FILE *fp1;
    fp1 = fopen(s.c_str(), "r");
    if (fp1 == nullptr) {
        LOG(ERROR, "Can not open file !");
        return -1;
    }
    FILE *fp2;
    fp2 = fopen(d.c_str(), "w");
    if (fp2 == nullptr) {
        LOG(ERROR, "Can not open file !");
        return -1;
    }

    char buff[1024] = {'\0'};
    int count;
    while((count = fread(buff, 1, 1024, fp1)) != 0)
        fwrite(buff, 1, count, fp2);

    fclose(fp1);
    fclose(fp2);

    return 0;
}

void FruitFSM::util_get_current_second_time_in_string(std::string &ss) {
    time_t ti;
    struct tm *p;
    time(&ti);
    p = gmtime(&ti);
    char sc[100];
    sprintf(sc, "%04d-%02d-%02d-%02d-%02d-%02d",
            (1900+p->tm_year), (1+p->tm_mon),p->tm_mday,
            (8+p->tm_hour), p->tm_min, p->tm_sec);
    ss = sc;
}

int FruitFSM::util_create_multi_dirs(const std::string& path) {
    char dn[256];
    int i, len;

    strcpy(dn, path.c_str());
    len = strlen(dn);
    if('/' != dn[len - 1]) {
        strcat(dn, "/");
        len++;
    }

    for(i=1; i<len; i++) {
        if('/' == dn[i]) {
            dn[i] = '\0';
            if(access(dn, F_OK) != 0) {
                if(mkdir(dn, 0777) == -1) {
                    LOG(ERROR,"Create directory error !");
                    return -1;
                }
            }
            dn[i] = '/';
        }
    }
    return 0;
}

int FruitFSM::util_get_min_from_multi_int(int num, ...) {
    va_list valist;
    int min;

    /* 为 num 个参数初始化 valist */
    va_start(valist, num);
    /* 访问所有赋给 valist 的参数 */
    min = INT32_MAX;
    for (int i = 0; i < num; i++) {
        int t = va_arg(valist, int);
        if (min > t) min = t;
    }
    /* 清理为 valist 保留的内存 */
    va_end(valist);

    return min;
}

int FruitFSM::util_get_max_from_multi_int(int num, ...) {
    va_list valist;
    int max;

    /* 为 num 个参数初始化 valist */
    va_start(valist, num);
    /* 访问所有赋给 valist 的参数 */
    max = INT32_MIN;
    for (int i = 0; i < num; i++) {
        int t = va_arg(valist, int);
        if (max < t) max = t;
    }
    /* 清理为 valist 保留的内存 */
    va_end(valist);

    return max;
}
